﻿using System;
using System.Collections.Generic;
using System.Configuration;
using System.ServiceModel.Description;
using System.ServiceModel.Security;
using Ipmce.RemoteVoting.Backend.DataAccess;
using Ipmce.RemoteVoting.Backend.VotingService.Contract;
using Ipmce.RemoteVoting.Backend.VotingService.Utils;
using Ipmce.RemoteVoting.Common.Tools;
using Ipmce.RemoteVoting.Common.Tools.Wcf.Unity;
using Ipmce.RemoteVoting.Common.Tools.Wcf.Unity.LifetimeManagers;
using Microsoft.Practices.Unity;
using ICandidateListProvider = Ipmce.RemoteVoting.Backend.VotingService.Contract.ICandidateListProvider;

namespace Ipmce.RemoteVoting.Backend.VotingService
{
	public class VotingServiceHostFactory : UnityServiceHostFactory
	{
		protected override bool OperationContextEnabled
		{
			get
			{
				return true;
			}
		}

		protected override IUnityContainer GetContainer()
		{
			var container = new UnityContainer();
			container.RegisterType<IPassportVoting, VotingService>(WcfPerRequest())
				.RegisterType<ICandidateListProvider, VotingService>(WcfPerRequest())
				.RegisterType<DataAccess.ICandidateListProvider, CandidateListProvider>(WcfPerRequest())
				.RegisterType<IVoterRepository, VoterRepository>(WcfPerRequest())
				.RegisterType<RemoteVotingContext>(WcfPerRequest(), new InjectionFactory(c =>
					new RemoteVotingContext(ConfigurationManager.AppSettings["RemoteVotingDataBase"])));

			return container;
		}

		protected override void CustomizeServiceBehaviors(KeyedByTypeCollection<IServiceBehavior> serviceBehaviors)
		{
			var behavior = serviceBehaviors.Find<ServiceCredentials>();
			if (behavior == null)
			{
				behavior = new ServiceCredentials();
				serviceBehaviors.Add(behavior);
			}
			behavior.ClientCertificate.Authentication.CertificateValidationMode = X509CertificateValidationMode.Custom;
			behavior.ClientCertificate.Authentication.CustomCertificateValidator =
				new CertificateValidator(ConfigurationManager.AppSettings["RootCa"]);
			behavior.UserNameAuthentication.UserNamePasswordValidationMode = UserNamePasswordValidationMode.Custom;
			var container = new UnityContainer();
			container.RegisterType<IVoterRepository, VoterRepository>()
				.RegisterType<IVoterRepositoryFactory, VoterRepositoryFactory>(new InjectionFactory(c =>
																		new VoterRepositoryFactory(
				                                                        	ConfigurationManager.AppSettings["RemoteVotingDataBase"])))
				.RegisterType<IPasswordCreator, PasswordCreator>()
				.RegisterType<UserNameValidator>();
			behavior.UserNameAuthentication.CustomUserNamePasswordValidator = container.Resolve<UserNameValidator>();
		}

		private static readonly Func<LifetimeManager> WcfPerRequest = () => new UnityOperationContextLifetimeManager();
	}
}